import React from 'react'
import PropTypes from 'prop-types'
import {connect} from 'dva'
import {Col, Form, message, Modal, Row} from 'antd'
import OrderDesc from './components/OrderDesc'
import ProductInfo from './components/ProductInfo'
import DeliverInfo from './components/DeliverInfo'
import OrderInfo from './components/OrderInfo'
import {queryArray} from "utils"
import ProductModal from "./components/ProductModal"

const confirm = Modal.confirm

class CreateOrder extends React.Component {

  constructor (props) {
    super(props)
    const {createOrder = {}, app: {user}} = props
    const {current = {}} = createOrder
    const {emp, totalAmount, realityPayAmount, address} = current
    this.state = {
      dataSource: [],
      count: 1,
      amount: (totalAmount || 0.00).toFixed(2),
      curDepot: -1,
      expressFee: 0,
      curAddr: address || {},
      addressInfo: '',
      realPayAmount: (realityPayAmount || 0.00).toFixed(2),
      extraAmount: {
        addAmount: 0,
        discountAmount: 0,
        prepayAmount: 0,
      },
      empAmounts: [0, 0, 0],
      belongEmp: emp || user,
    }
  }

  componentWillMount () {
    const {dispatch, createOrder: {current, formType}} = this.props
    if (formType === 'update') {
      dispatch({
        type: 'createOrder/findById',
        payload: {orderId: current.id},
      })
    }
  }

  componentWillReceiveProps ({createOrder}) {
    const {current, addressList = []} = createOrder
    const {
      customer = {},
      goodsDetailVOS,
      address,
      awardEmp1Money = 0,
      awardEmp2Money = 0,
      awardEmp3Money = 0,
      expressFee = 0,
      discountFee = 0,
      extraAmount = 0,
      orderAmount = 0,
      preAmount = 0,
      realityPayAmount = 0,
    } = current
    const {id} = customer
    const {dataSource, curAddr} = this.state
    const first = addressList[0]
    let flag = false
    const payload = {
      empAmounts: [(awardEmp1Money || 0).toFixed(2), (awardEmp2Money || 0).toFixed(2), (awardEmp3Money || 0).toFixed(2)],
      realPayAmount: (realityPayAmount || 0).toFixed(2),
      amount: (orderAmount || 0).toFixed(2),
      expressFee: (expressFee || 0).toFixed(2),
      extraAmount: {
        addAmount: (extraAmount || 0).toFixed(2),
        prepayAmount: (preAmount || 0).toFixed(2),
        discountAmount: (discountFee || 0).toFixed(2),
      }
    }
    if (address && address.isNew && curAddr !== address) {
      delete address.isNew
      payload['curAddr'] = address
      payload['addressInfo'] = address.provinceName + address.cityName + address.areaName + address.address
      flag = true
    } else if (first && first.customerId === id && !(curAddr.id) && addressList && addressList.length > 0) {
      // 初始化当前选中地址
      payload['curAddr'] = first
      payload['addressInfo'] = first.provinceName + first.cityName + first.areaName + first.address
      flag = true
    }
    if (dataSource.length === 0 && goodsDetailVOS) {
      payload['dataSource'] = goodsDetailVOS.map(item => {
        const {orderGoods = {}} = item
        item['salePrice'] = orderGoods['goodsPrice'] || 0
        item['num'] = orderGoods['goodsNum'] || 1
        item['discount'] = orderGoods['goodsDiscount'] || 10
        item['amount'] = CreateOrder.calc(item.salePrice, item.num, item.discount)
        return item
      })
      flag = true
    }

    if (flag) {
      this.setState(payload)
    }
  }

  static toNumber (val) {
    if (typeof val === 'string') {
      return parseFloat(val)
    }
    return val
  }

  static calc (salePrice, num, discount) {
    if (!salePrice || salePrice < 0) {
      message.warn("请输入正确的价格")
      return
    }
    salePrice = this.toNumber(salePrice)
    if (!num || num < 0) {
      num = 1
    }
    num = this.toNumber(num)
    if (!discount || discount < 0 || discount > 10) {
      discount = 10
    }
    discount = this.toNumber(discount)
    return ((salePrice * (discount / 10)) * num).toFixed(2)
  }

  updateAddr = (data) => {
    const {dispatch} = this.props
    data['isNew'] = true
    this.setState({
      curAddr: data,
      addressInfo: data.provinceName + data.cityName + data.areaName + data.address
    })
    dispatch({
      type: 'createOrder/hideAddrModal'
    })
  }

  validFields (params) {
    const {order: id} = params
    const {createOrder: {formType}} = this.props

    if (formType === 'update') {
      if (!id) {
        message.warn("参数异常，请联系管理员")
        console.warn("[参数异常] 更新订单 id 没有值！！！")
        return true
      }
    }
  }

  updateTotalAmount (newFee, newList, newExtraAmount = {}, newEmpAmounts = []) {
    const {dataSource: oldList, expressFee: oldFee, extraAmount = {}, empAmounts = [0, 0, 0]} = this.state
    let expressFee = parseFloat(newFee >= 0 ? newFee : oldFee)
    let dataSource = newList ? newList : oldList
    const {addAmount = 0, discountAmount = 0, prepayAmount = 0} = extraAmount
    let {addAmount: newAddAmount, discountAmount: newDiscountAmount, prepayAmount: newPrepayAmount} = newExtraAmount
    newAddAmount = parseFloat(newAddAmount >= 0 ? newAddAmount : addAmount)
    newDiscountAmount = parseFloat(newDiscountAmount >= 0 ? newDiscountAmount : discountAmount)
    newPrepayAmount = parseFloat(newPrepayAmount >= 0 ? newPrepayAmount : prepayAmount)
    newExtraAmount = {addAmount: newAddAmount, discountAmount: newDiscountAmount, prepayAmount: newPrepayAmount}

    newEmpAmounts[0] = newEmpAmounts[0] >= 0 ? newEmpAmounts[0] : empAmounts[0]
    newEmpAmounts[1] = newEmpAmounts[1] >= 0 ? newEmpAmounts[1] : empAmounts[1]
    newEmpAmounts[2] = newEmpAmounts[2] >= 0 ? newEmpAmounts[2] : empAmounts[2]

    let orderAmount = 0
    if (dataSource && dataSource.length > 0) {
      dataSource.map(_ => orderAmount += parseFloat(_.amount))
    }

    orderAmount = (expressFee + orderAmount + newAddAmount - newDiscountAmount)
    orderAmount = orderAmount < 0 ? 0 : orderAmount
    newEmpAmounts[0] = orderAmount - newEmpAmounts[1] - newEmpAmounts[2]
    let realPayAmount = (parseFloat(orderAmount) - newPrepayAmount)
    realPayAmount = (realPayAmount < 0 ? 0 : realPayAmount).toFixed(2)

    this.setState({
      dataSource,
      realPayAmount,
      amount: orderAmount.toFixed(2),
      extraAmount: newExtraAmount,
      empAmounts: newEmpAmounts,
    })
  }

  handleExtraAmountChange = (payload) => {
    const {addAmount, discountAmount, prepayAmount} = payload
    if (!addAmount && !discountAmount && !prepayAmount) {
      return
    }
    this.updateTotalAmount(undefined, undefined, payload)
  }

  handleEmpAmountChange = (payload) => {
    this.updateTotalAmount(undefined, undefined, undefined, payload)
  }

  handleChange = (type, val, record) => {
    const {dataSource} = this.state
    const {salePrice, num, discount} = record
    const exists = queryArray(dataSource, record.id, 'id')
    let tmpAmount = 0
    switch (type) {
      case 1:
        record.salePrice = val
        if (exists) {
          exists.salePrice = val
        }
        tmpAmount = CreateOrder.calc(val, num, discount)
        break
      case 2:
        record.num = val
        if (exists) {
          exists.num = val
        }
        tmpAmount = CreateOrder.calc(salePrice, val, discount)
        break
      case 3:
        record.discount = val
        if (exists) {
          exists.discount = val
        }
        tmpAmount = CreateOrder.calc(salePrice, num, val)
        break
      default:
        break
    }
    record.amount = tmpAmount
    this.updateTotalAmount()
  }

  handleDelete = (key) => {
    const dataSource = [...this.state.dataSource]
    const newDataSource = dataSource.filter(item => item.id !== key)
    this.setState({dataSource: newDataSource, curDepot: {}})
    this.updateTotalAmount(undefined, newDataSource)
  }

  handleAdd = (data) => {
    let num = 1
    const {dataSource, count} = this.state
    let errDepot = false
    dataSource.forEach(_ => {
      if (data.depotId !== _.depotId) {
        errDepot = true
        return
      }
    })
    if (errDepot) {
      message.warn("请选择与已存在商品相同仓库的商品")
      return
    }
    const {salePrice, discount = 0} = data
    const exists = queryArray(dataSource, data.id, 'id')
    if (exists) {
      num += (exists.num ? exists.num : 1)
    } else {
      dataSource.unshift(data)
    }
    const tmpAmount = CreateOrder.calc(salePrice, num, discount)
    data.num = num
    data.amount = tmpAmount
    if (exists) {
      exists.num = num
      exists.amount = tmpAmount
    }
    this.setState({dataSource, curDepot: {id: data.depotId, name: data.depotName}, count: count + data.num})
    this.updateTotalAmount()
  }

  handleExpressFeeChange = (val) => {
    this.setState({expressFee: val})
    this.updateTotalAmount(val)
  }

  onOk = () => {
    const target = this
    const {form: {validateFields}} = this.props
    validateFields((errors) => {
      if (errors) {
        return
      }

      confirm({
        title: "你确定要保存该订单吗?",
        onOk: () => {
          target.handleSubmit()
        },
        onCancel () {
          console.log('Cancel')
        },
      })
    })
  }

  handleSubmit () {
    const {createOrder, dispatch} = this.props

    const {
      curAddr,
      addressInfo,
      dataSource,
      expressFee,
      extraAmount: {addAmount, discountAmount, prepayAmount},
      curDepot: {id, name}, empAmounts
    } = this.state
    const {
      id: orderId,
      requireSendTime,
      prepayTypeId,
      prepayTypeName,
      customerSourceId,
      customerSourceName,
      expressTypeId,
      expressTypeName,
      awardEmp2Id,
      awardEmp3Id,
      customerRemark,
      empRemark,
      current,
      route,
    } = createOrder
    const {customer, awardEmp1Id} = current
    const params = {
      order: {
        id: orderId,
        customerWxId: customer.id,
        extraFee: addAmount,
        expressFee: expressFee,
        discountFee: discountAmount,
        preAmount: prepayAmount,
        wxId: customer.operatorWxId.wxId,
        wxNo: customer.operatorWxId.wxNo,
        address: {id: curAddr.id},
        unreceivedAmount: 0,
        requireSendTime: requireSendTime ? requireSendTime.format("YYYY-MM-DD hh:mm:ss") : undefined,
        prepayTypeId,
        prepayTypeName,
        addressInfo,
        customerSourceId,
        customerSourceName,
        expressTypeId,
        expressTypeName,
        awardEmp1Id: awardEmp1Id || customer.operatorWxId.belongEmp.id,
        awardEmp1Money: empAmounts[0],
        awardEmp2Id,
        awardEmp2Money: empAmounts[1],
        awardEmp3Id,
        awardEmp3Money: empAmounts[2],
        customerRemark,
        empRemark,
        depotId: id,
        depotName: name,
      },
      goodsList: dataSource.map(_ => ({
        goodsId: _.id,
        goodsNum: _.num,
        goodsDiscount: _.discount,
        name: _.goodsName,
        goodsPrice: _.salePrice,
        goodsSn: _.sn,
      })),
    }

    if (this.validFields(params)) {
      return
    }

    dispatch({
      type: `createOrder/create`,
      payload: params,
    }).then(() => {
      dispatch({
        type: 'app/closeTab',
        payload: {
          key: route,
        }
      })
    })
  }

  render () {
    const {createOrder, loading, dispatch, app, form} = this.props
    const {curAddr, dataSource, amount, curDepot, expressFee, realPayAmount, belongEmp, empAmounts, extraAmount} = this.state
    const {
      productModalVisible,
      addressModalVisible,
      addressList,
      depotList,
      expressType,
      prepayType,
      customerChannel,
      empDataSource,
      current,
    } = createOrder

    const {customer} = current
    const productInfoProps = {
      amount,
      dataSource,
      productModalVisible,
      current,
      form,
      handleDelete: this.handleDelete,
      showModal () {
        dispatch({
          type: 'createOrder/showProductModal',
        })
      },
      handleChange: this.handleChange,
    }

    const handleAdd = this.handleAdd

    const productModalProps = {
      visible: productModalVisible,
      width: 1080,
      maskClosable: false,
      footer: null,
      title: '添加商品',
      current,
      wrapClassName: 'vertical-center-modal',
      onOk: undefined,
      onCancel () {
        dispatch({
          type: 'createOrder/hideProductModal',
        })
      },
      handleSelect (customer) {
        handleAdd(customer)
        dispatch({
          type: 'createOrder/hideProductModal',
        })
      },
    }

    const orderDescProps = {
      amount,
      dispatch,
      current,
      form,
      app,
      onOk: this.onOk,
    }

    const deliverInfoProps = {
      customer,
      expressType,
      addressList,
      curAddr,
      curDepot,
      depotList,
      dispatch,
      loading,
      expressFee,
      current,
      form,
      updateAddr: this.updateAddr,
      modalVisible: addressModalVisible,
      onSelect () {
        dispatch({
          type: 'createOrder/queryAddress',
          payload: {customerId: customer.id}
        })
        dispatch({
          type: 'createOrder/showAddrModal',
        })
      },
      handleExpressFeeChange: this.handleExpressFeeChange,
    }

    const orderInfoProps = {
      amount,
      prepayType,
      customerChannel,
      empDataSource,
      realPayAmount,
      belongEmp,
      empAmounts,
      extraAmount,
      dispatch,
      current,
      form,
      onOk: this.onOk,
      handleSearch (key) {
        if (key) {
          dispatch({
            type: 'createOrder/searchEmp',
            payload: {
              key,
            },
          })
        }
      },
      handleExtraAmountChange: this.handleExtraAmountChange,
      handleEmpAmountChange: this.handleEmpAmountChange,
    }

    return (
      <Form layout="horizontal" onSubmit={this.handleSubmit} style={{marginTop: 8}}>
        <OrderDesc {...orderDescProps}>
          <Row gutter={24}>
            <Col span={24}>
              <ProductInfo {...productInfoProps}/>
            </Col>
          </Row>
          <Row gutter={24}>
            <Col span={24}>
              <DeliverInfo {...deliverInfoProps}/>
            </Col>
          </Row>
          <Row gutter={24}>
            <Col span={24}>
              <OrderInfo {...orderInfoProps}/>
            </Col>
          </Row>
        </OrderDesc>
        {productModalVisible && <ProductModal {...productModalProps}/>}
      </Form>
    )
  }
}

const WrappedCreateOrder = Form.create()(CreateOrder)

WrappedCreateOrder.propTypes = {
  createOrder: PropTypes.object,
  location: PropTypes.object,
  dispatch: PropTypes.func,
  loading: PropTypes.object,
}

export default connect(({app, createOrder, loading}) => ({app, createOrder, loading}))(WrappedCreateOrder)
